package com.africanmoviesmobile.ui;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;

import org.pixmob.httpclient.HttpClientException;

import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.africanmoviesmobile.R;
import com.africanmoviesmobile.util.bitmap.ImageCache.ImageCacheParams;
import com.africanmoviesmobile.util.bitmap.ImageFetcher;
import com.africanmoviesmobile.webservice.AmmWebService;
import com.africanmoviesmobile.webservice.BasicAsyncCallback;
import com.africanmoviesmobile.webservice.WebServiceException;
import com.africanmoviesmobile.webservice.inf.Celeb;
import com.africanmoviesmobile.webservice.inf.Movie;

public class SearchableActivity extends BaseActivity implements OnItemClickListener, OnScrollListener{

	private ListView mSearchableListView;
	private LayoutInflater mLayoutInflater;
	private LinearLayout mEmptySearchResult;
	private LinearLayout mLoadingProgress;
	
	private TextView mSearchListHeader;
	
	private ImageFetcher mThumbnailImageFetcher;
	
	AmmWebService mAmmWebService;
	
	private SearchableListAdapter mSearchableListAdapter;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.searchable_activity);
	    
	    int thumbnailWidth = getResources().getDimensionPixelSize(R.dimen.thumbnail_width);
		int thumbnailHeight = getResources().getDimensionPixelSize(R.dimen.thumbnail_height);
		mThumbnailImageFetcher = new ImageFetcher(this, thumbnailWidth, thumbnailHeight);
		mThumbnailImageFetcher.setLoadingImage(R.drawable.empty_photo);
		mThumbnailImageFetcher.addImageCache(getSupportFragmentManager(), new ImageCacheParams(this, CACHE_DIR_THUMBNAIL));
		
		mSearchableListAdapter = new SearchableListAdapter();
		
		mLayoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		mLoadingProgress = (LinearLayout) mLayoutInflater.inflate(R.layout.loading_progress_small, null);
		
		mSearchListHeader = (TextView) findViewById(R.id.search_list_header);
		mEmptySearchResult = (LinearLayout) findViewById(R.id.empty_search_result);
		
		View header = mLayoutInflater.inflate(R.layout.header_2, null);
		((TextView) header.findViewById(R.id.header_text)).setText(R.string.search_results);
    	
		mSearchableListView = (ListView) findViewById(R.id.list);
		mSearchableListView.setDividerHeight(0);
		mSearchableListView.setEmptyView(mLoadingProgress);
		mSearchableListView.addHeaderView(header);
		mSearchableListView.setAdapter(mSearchableListAdapter);
		mSearchableListView.setOnItemClickListener(this);
		mSearchableListView.setOnScrollListener(this);
		
		mAmmWebService = AmmWebService.getInstance(this);
	    
	    handleIntent(getIntent());
	}

	@Override
	protected void onNewIntent(Intent intent) {
	    setIntent(intent);
	    handleIntent(intent);
	}

	private void handleIntent(Intent intent) {
		
	    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
	    
	    	String query = intent.getStringExtra(SearchManager.QUERY);
	    	
	    	mSearchListHeader.setText(String.format(getResources().getString(R.string.search_list_header), query));
		    mSearchableListAdapter.clear();
		    
		    mEmptySearchResult.setVisibility(View.GONE);
		    
	    	Hashtable<String, String> params = new Hashtable<String, String>();
	    	params.put("query", query);
	    	params.put("email", getLoginEmail());
		  
	    	mAmmWebService.searchAmm(params, new BasicAsyncCallback() {

				public void onComplete(final Object[] result, final Object state) {
					
					Movie[] movies = (Movie[]) result[0];
					
					Celeb[] celebs = (Celeb[]) result[1];
					
					if((movies != null) || (celebs != null)){
												
						if (movies != null) {																	
							for (int i = 0; i < movies.length; i++) {
								final Movie movie = (Movie) (movies[i]);
								runOnUiThread(new Runnable() {public void run() { mSearchableListAdapter.add(movie); }});
							}
						} 
						
						if (celebs != null) {			
							for (int i = 0; i < celebs.length; i++) {
								final Celeb celeb = (Celeb) (celebs[i]);
								runOnUiThread(new Runnable() {public void run() { mSearchableListAdapter.add(celeb); }});
							}
						} 
					}else{
						runOnUiThread(new Runnable() {
							public void run() {
								mEmptySearchResult.setVisibility(View.VISIBLE);
							}
						});
					}
					
				}

				public void onHttpClientException(final HttpClientException e, final Object state) {
					Log.w("AMM HttpClientException:", e.getMessage());
				}
				
				public void onIOException(final IOException e, final Object state) {
					Log.w("AMM IOException:", e.getMessage());
				}

				public void onWebServiceException(final WebServiceException e, final Object state) {
					Log.w("AMM WebServiceException:", e.getMessage());
					toastMessage(e.getMessage());
				}

			}, null);
	      
	    }
	}
	
	@Override
    public void onResume() {
        super.onResume();
        mThumbnailImageFetcher.setExitTasksEarly(false);
        mSearchableListAdapter.notifyDataSetChanged();
    }

    @Override
    public void onPause() {
        super.onPause();
        mThumbnailImageFetcher.setPauseWork(false);
        mThumbnailImageFetcher.setExitTasksEarly(true);
        mThumbnailImageFetcher.flushCache();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mThumbnailImageFetcher.closeCache();
    }
	
    @Override
   	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    	if(mSearchableListView.getItemAtPosition(position) != null){
    		if(mSearchableListView.getItemAtPosition(position) instanceof Movie){
    			Movie movie = (Movie) mSearchableListView.getItemAtPosition(position);
        		final Intent intent = new Intent(this, MovieDetailActivity.class);
        		intent.putExtra(MovieDetailActivity.EXTRA_MOVIE_ID, movie.getId());
                startActivity(intent);
        	}else{
        		Celeb celeb = (Celeb) mSearchableListView.getItemAtPosition(position);
        		final Intent intent = new Intent(this, CelebDetailActivity.class);
        		intent.putExtra(CelebDetailActivity.EXTRA_CELEB_ID, celeb.getId());
                startActivity(intent);
        	}
    	}
   	}
    
	@Override
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		// Pause fetcher to ensure smoother scrolling when flinging
        if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
        	mThumbnailImageFetcher.setPauseWork(true);
        } else {
        	mThumbnailImageFetcher.setPauseWork(false);
        }
	}
	public class SearchableListAdapter extends BaseAdapter {

		private static final int VIEW_TYPE_MOVIE = 0;
		private static final int VIEW_TYPE_CELEB = 1;
		
		private Vector<Object> mListElements = new Vector<Object>();
		
		private class ViewHolder {
			public TextView mMovieTitle;
			public TextView mMovieCast;
    	    public ImageView mMovieCover;
    	    public ImageView mMovieRating;
    	    public TextView mCelebName;
    	    public ImageView mCelebPhoto;
    	}
		
        public SearchableListAdapter() {
        }

        public int getCount() {
        	if (mListElements.isEmpty()) {
    			return 0;
    		} else {
    			return mListElements.size();
    		}
        }

        public Object getItem(int position) {
        	return mListElements.elementAt(position);
        }

        public long getItemId(int position) {
    		return position;
        }
        
        public int getItemViewType(int position) {
        	if(mListElements.elementAt(position) instanceof Movie){
        		return VIEW_TYPE_MOVIE;
        	}else{
        		return VIEW_TYPE_CELEB;
        	}
        }

        public int getViewTypeCount() {
            return 2;
        }

        public View getView(int position, View convertView, ViewGroup parent) {

        	ViewHolder holder;
        	
        	View searchableRow = convertView;
        	
        	if(searchableRow == null){
        		
        		holder  = new ViewHolder();
        		
        		if(getItemViewType(position) == VIEW_TYPE_MOVIE){
        			searchableRow = mLayoutInflater.inflate(R.layout.movie_listview_row, parent, false);
            		holder.mMovieTitle = (TextView) searchableRow.findViewById(R.id.movie_title);
            		holder.mMovieCast = (TextView) searchableRow.findViewById(R.id.movie_cast);
            		holder.mMovieRating = (ImageView) searchableRow.findViewById(R.id.movie_rating);
            		holder.mMovieCover = (ImageView) searchableRow.findViewById(R.id.movie_cover);
        		}else{
        			searchableRow = mLayoutInflater.inflate(R.layout.celeb_listview_row, parent, false);
                    holder.mCelebPhoto = (ImageView) searchableRow.findViewById(R.id.celeb_photo);
            		holder.mCelebName = (TextView) searchableRow.findViewById(R.id.celeb_name);
        		}
        		
        		searchableRow.setTag(holder);
        	}else{
        		holder = (ViewHolder) searchableRow.getTag();
        	}
        	
        	if(getItemViewType(position) == VIEW_TYPE_MOVIE){
        		Movie movie = (Movie) mListElements.elementAt(position);
        		holder.mMovieTitle.setText(movie.getTitle());
            	holder.mMovieCast.setText(movie.getShortCast());
            	holder.mMovieRating.setImageResource(mRatingsStarDarkArray[movie.getRatings()]);
            	mThumbnailImageFetcher.loadImage(movie.getCover(), holder.mMovieCover);
        	}else{
        		Celeb celeb = (Celeb) mListElements.elementAt(position);
        		holder.mCelebName.setText(celeb.getName());
            	mThumbnailImageFetcher.loadImage(celeb.getDefaultPhoto(), holder.mCelebPhoto);
        	}
        	
        	return searchableRow;
        }

        public void clear() {
        	mListElements.clear();
            notifyDataSetChanged();
        }
        
        public void add(Object data) {
        	mListElements.addElement(data);
            notifyDataSetChanged();
        }
	}
}
